#pragma once
//事件循环类，主要包含两个大模块，一个是channel一个是poller(poll和epoll的抽象类)
#include<functional>
#include<vector>
#include<atomic>
#include<memory>
#include<mutex>
#include"noncopyable.h"
#include"Timestamp.h"
#include"CurrentThread.h"

class Channel;
class Poller;

class Eventloop:noncopyable
{
    public:
        using Functor=std::function<void()>;
        Eventloop();
        ~Eventloop();

        void loop();//开启事件循环
        void quit();//退出事件循环
        Timestamp pollReturnTime() const {return pollReturnTime_;}

        void runInLoop(Functor cb);//在当前loop中执行cb
        void queueInLoop(Functor cb);//把cb放进队列中，唤醒loop所在线程执行cb

        void wakeup();//用来唤醒loop所在线程的

        //下面这三个EventLoop的方法，用来调用poller的方法
        void updateChannel(Channel* channel);
        void removeChannel(Channel* channel);
        bool hasChannel(Channel* channel);
        //判断Eventloop对象是否在自己的线程里面
        bool isInLoopThread() const {return threadId_ == CurrentThread::tid();}

    private:
        void handleRead();
        void doPendingFunctors();
        using ChannelList=std::vector<Channel*>;
        std::atomic_bool looping_;//原子操作，通过CAS实现的
        std::atomic_bool quit_;//标识退出loop循环(客户端断开之后，关闭事件循环)，从boost库转成C++，实现更好地跨平台
       
        const pid_t threadId_;//记录当前loop所在的线程id
        Timestamp pollReturnTime_;//poller返回发生事件的channels的时间点
        std::unique_ptr<Poller> poller_;

        int wakeupFd_;//主要作用，当mainloop获取一个新用户的channel，通过轮循算法选择一个subloop，通过该成员唤醒subloop处理channel
        std::unique_ptr<Channel> wakeupChannel_;

        ChannelList activeChannels_;
       

        std::atomic_bool callingPendingFunctors_;//标识当前loop是否有需要回执的回调操作
        std::vector<Functor> pendingFunctors_;//存储loop需要执行的所有回调操作
        std::mutex mutex_;//互斥锁，保护上面vector容器的线程安全操作

    };